<?php
/**
 * @ScriptName: filter.php
 * @Function: Defines an component which justifies the controller Paginator,
 * @Package: SME.Component.Filter,
 * @Insparation: tomato,
 * @Author: tomato at<wangshijun2010@gmail.com>,
 * @License: http://www.opensource.org/licenses/mit-license.php The MIT License
 * @CreateDate: 2010-01-16 10:11:38
 */

Class FilterComponent extends Object {
    /**
     * paginator 内置的参数选项, 这里我们不能做任何修改, 否则会引起错误
     */
    private $_blacklist = array('page', 'sort', 'direction');

    /**
     * 指明那些字段需要使用LIKE模式搜索, 那些事日期字段
     */
    private $_fields = array(
        'like' => array('name', 'title', 'content', 'introduction', 'requirement', 'workplace', 'number'),
        'date' => array('created', 'modified')
    );

    /**
     * 其他选项,
     */
    private $_options = array(
        'date' => 'Y-m-d'
    );

    /**
     * 设定过滤选项, 比如日期的搜索模式:
     */
    public function options($options=array()){
        $this->_options = array_merge($this->_options, $options);
    }

    /**
     * 主函数: 为Controller.Index设定查询参数, 当然这要依赖于客户端传入的参数
     * @access: public
     * @param: Controller $controller
     * @param: array $options
     * @return: null
     */
    public function apply(&$controller, $fields=array(), $options=array()){
        $this->options($options);
        if(empty($fields)){ return false; }
        if(empty($controller->params['named'])){ return false; }
        //$model = $controller->modelClass;
        $blacklist = $this->_blacklist;
        $controller->paginate['limit'] = 10;
        $controller->paginate['conditions'] = array();
        $filters = array_merge($fields, $controller->params['named']);
        foreach($filters as $field=>$condition){
            if(!in_array($field, $blacklist) && !empty($condition)){
                $controller->paginate['conditions'][$model.'.'.$field] = $condition;
            }
        }
        $this->_prepareLikeFields(&$controller, $filters, $model);
        $this->_prepareDateFields(&$controller, $filters, $model);
    }

    /**
     * 调整使用LIKE来搜素匹配记录的字段, 比如, title, name , content, introduction
     *
     * @param: Controller $controller
     * @param: array $filters
     * @param: string $model
     * @return: null
     */
    private function _prepareLikeFields(&$controller, $filters, $model){
        $likes = $this->_fields['like'];
        foreach($likes as $i=>$like){
            if(!empty($filters[$like])){
                unset($controller->paginate['conditions'][$model.'.'.$like]);
                $controller->paginate['conditions'][$model.'.'.$like.' LIKE '] = '%'.$filters[$like].'%';
            }
        }
    }

    /**
     * 调整日期搜索来匹配记录的字段, 如created, modifed
     *
     * @param: Controller $controller
     * @param: array $filters
     * @param: string $model
     * @return: null
     */
    private function _prepareDateFields(&$controller, $filters, $model){
        $dates = $this->fields['date'];
        $format = $this->_options['date'];
        foreach($dates as $i=>$date){
            if(!empty($filters[$date])){
                unset($controller->paginate['conditions'][$model. '.' .$date]);
                $time = strtotime($filters[$date] . '+1day');
                $today = date($format, strtotime($filters[$date]));
                $tomorrow = date($format, $time);
                $controller->paginate['conditions'][$model. '.' .$date.' BETWEEN ? AND ?'] = array($today, $tomorrow);
            }
        }
    }

}

?>